package com.ruoyi.web.controller.clientb;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.dyplsapi20170525.models.BindAxnRequest;
import com.aliyun.dyplsapi20170525.models.BindAxnResponse;
import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
import com.aliyun.teaopenapi.models.Config;

import com.ruoyi.common.annotation.CheckMiniUser;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.constant.HttpStatus;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;

import com.ruoyi.common.core.domain.entity.MinUser;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.entity.SysVerification;
import com.ruoyi.common.core.domain.model.LoginBody;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.exception.CustomException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.StringUtils;

import com.ruoyi.common.utils.TokenUtil;
import com.ruoyi.common.utils.aliyunutils.HttpUtils;
import com.ruoyi.common.utils.spring.SpringUtils;

import com.ruoyi.common.wxServe.WeChatServe;
import com.ruoyi.common.wxServe.bo.Auth2SessionBo;
import com.ruoyi.framework.manager.AsyncManager;
import com.ruoyi.framework.manager.factory.AsyncFactory;
import com.ruoyi.framework.web.service.SysLoginService;
import com.ruoyi.framework.web.service.TokenService;


import com.ruoyi.system.domain.Person;
import com.ruoyi.system.domain.vo.LoginVo;
import com.ruoyi.system.domain.vo.SyVirtualNumberVo;
import com.ruoyi.system.mapper.PersonMapper;
import com.ruoyi.system.mapper.PtestingMapper;
import com.ruoyi.system.mapper.SysDeptMapper;
import com.ruoyi.system.mapper.SysUserMapper;
import com.ruoyi.system.service.*;

import io.swagger.annotations.ApiOperation;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.*;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

import static com.ruoyi.web.controller.system.SysVerificationController.createClient;

@RequestMapping("/mini/cb/")
@RestController
public class IndexClibController extends BaseController {

    @Autowired
    private ISysVerificationService iSysVerificationService;
    @Autowired
    private IPersonService personService;
    @Autowired
    private IMinUserService minUserService;
    @Autowired
    private SysLoginService loginService;
    @Autowired
    private PersonMapper personMapper;
    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private WeChatServe weChatServe;
    @Autowired
    private ISysDeptService deptService;
    @Autowired
    private RedisCache redisCache;  //缓存
    @Autowired
    private SysDeptMapper sysDeptMapper;
    @Autowired
    private TokenService tokenService;

    /**
     * 参数：通过openid获取token
     *
     * @param loginVo
     * @return
     */
//    @ApiOperation("登录")
    @PostMapping("autoLogin")
    @Deprecated
    public AjaxResult autoLogin(@RequestBody LoginVo loginVo) {
        if (StringUtils.isBlank(loginVo.getOpenid())) {
            throw new CustomException("openid缺失");
        }
        final String token = minUserService.autoLogin(loginVo);
        return AjaxResult.success((Object) token);
    }

    /**
     * 参数：用户电话/用户名称/code/openid
     *
     * @param loginVo
     * @return
     */
//    @ApiOperation("登录")
    @PostMapping("loginByMini")
    public Map loginByMini(@RequestBody LoginVo loginVo) {
        Map<String, String> resPart1 = new HashMap<String, String>();
        if (StringUtils.isBlank(loginVo.getUphone())) {
            if (StringUtils.isBlank(loginVo.getCode())) {
                throw new CustomException("code缺失");
            }
            final Auth2SessionBo auth2SessionBo = weChatServe.authCode2Session(loginVo.getCode());
            //loginVo.setOpenid(auth2SessionBo.getOpenid());

            MinUser minUser = minUserService.selectMinUserByOpenId(auth2SessionBo.getOpenid());

            if (minUser == null) {
                resPart1.put("code", "200");
                resPart1.put("sessionKey", auth2SessionBo.getSession_key());
                resPart1.put("openid", auth2SessionBo.getOpenid());
                return resPart1;
            } else {
                String token = TokenUtil.createToken(minUser.getOpenid());
                resPart1.put("code", "300");
                resPart1.put("token", token);
                return resPart1;
            }
        } else {
            if (StringUtils.isBlank(loginVo.getUname())) {
                loginVo.setUname(loginVo.getUphone());
            }
            final String token = minUserService.autoLogin(loginVo);
            resPart1.put("code", "300");
            resPart1.put("token", token);
            return resPart1;
        }
    }


    //    @ApiOperation("根据手机号获取用户信息")
    @CheckMiniUser
    @GetMapping(value = "healthInfoStatus")
    public AjaxResult healthInfoStatus() {
        final MinUser minUser = getMinUser();
        if (!StringUtils.isEmpty(minUser.getOpenid())) {

            List<HashMap<String, Object>> hashMaps = minUserService.selectPersonByOpenId(minUser.getOpenid());
            if (hashMaps.size() > 0) {
                Map map = new HashMap();
                map.put("status", 1);
                return AjaxResult.success(map);
            }
        }
        Map map = new HashMap();
        map.put("status", 0);
        return AjaxResult.success(map);
    }


    /**
     * 新增参数配置
     */
//    @ApiOperation("新增")
    @PostMapping("insertPerson")
    public Map saveOrUpdatePerson(@RequestBody Person person) throws ParseException {
        Map<String, String> resPart1 = new HashMap<String, String>();
        //获取手机号校验与身份校验的状态
        SysVerification sysVerification = iSysVerificationService.selectVerification();
        String mobileVerification = sysVerification.getMobileVerification();
        String state = JSON.parseObject(mobileVerification).getString("state");
        if ("1".equals(state)) {
            if (StringUtils.isNotNull(person.getYzm()) && StringUtils.isNotNull(person.getPhoneNumber())) { //验证码手机号都不允许为空
                String cacheObject = redisCache.getCacheObject(person.getPhoneNumber() + ""); //从redis中获取验证
                if (StringUtils.isEmpty(cacheObject)) { //为空的情况下手机号失败
                    resPart1.put("code", "503");  //身份校验失败
                    return resPart1;
                }
                if (!cacheObject.equalsIgnoreCase(person.getYzm())) {
                    resPart1.put("code", "503");  //身份校验失败
                    return resPart1;
                }
            } else {
                resPart1.put("code", "503");  //身份校验失败
                return resPart1;
            }
        }
        //0新增1导入2小程序录入3经营录入
        if (person.getSource().equals("2")) {
            final MinUser minUser = getMinUser();
            person.setOpenId(minUser.getOpenid());//openId
        }
        String cardIdVerification = sysVerification.getCardIdVerification();
        String state1 = JSON.parseObject(cardIdVerification).getString("state");
        if ("1".equals(state1)) {
            //根据姓名身份证号码查询第三方做身份校验
            String s = this.getcardId(person.getPersonName(), person.getCardId());
            //为空的时候是没有校验条数了
            if (StringUtils.isEmpty(s)) {
                resPart1.put("code", "505");  //身份校验失败
                return resPart1;
            }
            if (StringUtils.isNotEmpty(s)) {
                JSONObject jo = JSONObject.parseObject(s);
                if (!jo.get("respCode").equals("0000")) {
                    resPart1.put("code", "505");  //身份校验失败
                    return resPart1;
                }
                person.setPersonAge(Integer.parseInt(jo.get("age") + "")); //年龄
                if (jo.get("sex").equals("M")) {
                    person.setSex("男");
                } else {
                    person.setSex("女");
                }
            }
        }
        List<Person> people = personService.SelectCarid(person);
        if (people.size() > 0) {
            resPart1.put("code", "400");
            return resPart1;
        }
        //根据登录的用户获取权限
        person.setExamine(1); //未审核状态
        int i = personService.insertPersonXcx(person);
        if (i == 2) {
            resPart1.put("code", "400");
            return resPart1;
        }
        resPart1.put("code", "200");
        return resPart1;
    }


    //根据查回来的手机号判断是否是虚拟号
    @GetMapping("/getXniHao")
    public Map getXniHao(@RequestParam String phoneNumber) throws Exception {
        Map map = new HashMap<>();
        if(StringUtils.isNotEmpty(phoneNumber)){
//获取虚拟号校验{"state":1,"poolKey":"FC100000158802191",
// "accessKeySecret":"BdNBUftG0TlfyPAUHjvIryrOywa4Qe","accessKeyId":"LTAI5tQFRoXAJgkXkPZW7vat","expiration":"11"}
            SysVerification sysVerification = iSysVerificationService.selectVerification();
            String virtualNumber = sysVerification.getVirtualNumber();
            JSONObject jsonObject = JSON.parseObject(virtualNumber);
            String state = jsonObject.getString("state");
            if ("1".equals(state)) {
                SyVirtualNumberVo syVirtualNumberVo = new SyVirtualNumberVo();
                syVirtualNumberVo.setAccessKeyId(jsonObject.get("accessKeyId")+"");
                syVirtualNumberVo.setAccessKeySecret(jsonObject.get("accessKeySecret")+"");
                syVirtualNumberVo.setPoolKey(jsonObject.get("poolKey")+"");
                syVirtualNumberVo.setExpiration(Integer.parseInt(jsonObject.get("expiration")+""));
                syVirtualNumberVo.setPhone(phoneNumber);
                return  getphoneHm(syVirtualNumberVo);
            }

        }
        map.put("data", phoneNumber);
        map.put("code", 200);
        map.put("msg", "手机号为");
        return map;
    }


    /**
     * 根据身份证号查询用户信息
     */
    @ApiOperation("根据身份证号查询用户信息")
    @GetMapping("selectCarid")
    public AjaxResult selectCarid(@RequestParam String phoneNumber) {
        Person person = new Person();
        person.setCardId(phoneNumber);
        List<Person> people = personService.SelectCarid(person);
        if (people.size() > 0) {
            return AjaxResult.success(people.get(0));
        }
        return AjaxResult.success(people);
    }

    /**
     * 根据用户openid查询用户信息
     */
//    @ApiOperation("根据用户openid查询用户信息")
    @RequestMapping("selectPersonByOpenId")
    public AjaxResult selectPersonByOpenId() {
        final MinUser minUser = getMinUser();
        List<Person> people = new ArrayList<Person>();
        if (!StringUtils.isEmpty(minUser.getOpenid())) {
            Person person = new Person();
//            person.setState(1);
            person.setOpenId(minUser.getOpenid());
            people = personMapper.selectPersonByDeptId(person);
            if (people.size() > 0) {
                Person person1 = people.get(0);
                return AjaxResult.success(person1);
            }
        }
        return AjaxResult.success(people);
    }

    /**
     * 登录方法
     *
     * @param loginBody 登录信息
     * @return 结果
     */
    @RequestMapping("/loginApplet")
    public AjaxResult loginApplet(@RequestBody LoginBody loginBody) {
        AjaxResult ajax = AjaxResult.success();
        // 生成令牌
        String token = loginService.loginApplet(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(), loginBody.getUuid());
        ajax.put(Constants.TOKEN, token);
        return ajax;
    }

    /**
     * 小程序获取行业
     */
    @GetMapping("listBm")
    public AjaxResult list(SysDept dept) {
        List<SysDept> depts = sysDeptMapper.selectDeptList(dept);
        return AjaxResult.success(deptService.buildDeptTreeSelect(depts));
    }

    /**
     * 退出处理
     *
     * @return
     */
    @PostMapping("onLogoutSuccess")
    public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        LoginUser loginUser = tokenService.getLoginUser(request);
        if (StringUtils.isNotNull(loginUser)) {
            String userName = loginUser.getUsername();
            // 删除用户缓存记录
            tokenService.delLoginUser(loginUser.getToken());
            // 记录用户退出日志
            AsyncManager.me().execute(AsyncFactory.recordLogininfor(userName, Constants.LOGOUT, "退出成功"));
        }
        ServletUtils.renderString(response, JSON.toJSONString(AjaxResult.error(HttpStatus.SUCCESS, "退出成功")));
    }


    /**
     * 身份证校验
     *
     * @param nane
     * @param cardId
     * @return
     */
    public String getcardId(String nane, String cardId) {
        String host = "https://idenauthen.market.alicloudapi.com";
        String path = "/idenAuthentication";
        String method = "POST";
        SysVerification sysVerification = iSysVerificationService.selectVerification();
        String cardIdVerification = sysVerification.getCardIdVerification();
        String appcode = JSON.parseObject(cardIdVerification).getString("appcode");
        Map<String, String> headers = new HashMap<String, String>();
        //最后在header中的格式(中间是英文空格)为Authorization:APPCODE 83359fd73fe94948385f570e3c139105
        headers.put("Authorization", "APPCODE " + appcode);
        //根据API的要求，定义相对应的Content-Type
        headers.put("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
        Map<String, String> querys = new HashMap<String, String>();
        Map<String, String> bodys = new HashMap<String, String>();
        bodys.put("idNo", cardId);
        bodys.put("name", nane);
        String fanhui = "";
        try {
            /**
             * 重要提示如下:
             * HttpUtils请从
             * https://github.com/aliyun/api-gateway-demo-sign-java/blob/master/src/main/java/com/aliyun/api/gateway/demo/util/HttpUtils.java
             * 下载
             *
             * 相应的依赖请参照
             * https://github.com/aliyun/api-gateway-demo-sign-java/blob/master/pom.xml
             */
            HttpResponse response = HttpUtils.doPost(host, path, method, headers, querys, bodys);
            System.out.println(response.toString());
            //获取response的body
            fanhui = EntityUtils.toString(response.getEntity());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return fanhui;
    }


    /**
     * 手机号验证码校验
     *
     * @param person
     * @return
     */
    @PostMapping("getstageDx")
    public Map getstageDx(@RequestBody Person person) {
        HashMap hashMap = new HashMap();
        if (StringUtils.isNotNull(person.getPhoneNumber())) {
            String phoneNumber = person.getPhoneNumber() + "";
            try {
                SysVerification sysVerification = iSysVerificationService.selectVerification();
                String mobileVerification = sysVerification.getMobileVerification();
                //生成验证码并存储到Redis中
                String code = UUID.randomUUID().toString().substring(0, 4);
                com.aliyun.dysmsapi20170525.Client client = createClient(JSON.parseObject(mobileVerification).getString("accessKeyId"), JSON.parseObject(mobileVerification).getString("accessKeySecret"));
                SendSmsRequest sendSmsRequest = new SendSmsRequest().setPhoneNumbers(person.getPhoneNumber() + "").setSignName(JSON.parseObject(mobileVerification).getString("signName")).setTemplateCode(JSON.parseObject(mobileVerification).getString("templateCode")).setTemplateParam("{\"code\":\"" + code + "\"}");
                // 复制代码运行请自行打印 API 的返回值
                SendSmsResponse sendSmsResponse = client.sendSms(sendSmsRequest);
                String code1 = sendSmsResponse.getBody().getCode();
                if (code1.equalsIgnoreCase("ok")) {
                    //存入redis
                    redisCache.setCacheObject(phoneNumber, code);
                    redisCache.expire(phoneNumber, 300l); //设置失效时间 单位秒
                    //发送成功
                    hashMap.put("code", 200);
                    hashMap.put("srm", "短信发送成");
                } else {
                    //发送失败
                    hashMap.put("code", 400);
                    hashMap.put("srm", "短信发送失败");
                }
            } catch (Exception e) {
                hashMap.put("code", 400);
                hashMap.put("srm", "短信发送失败");
            }
        }
        return hashMap;
    }


    @GetMapping("/thirdPartyVerification")
    public SysVerification thirdPartyVerification() {
        SysVerification sysVerification = iSysVerificationService.selectVerification();
        return sysVerification;
    }
    /**
     * 使用AK&SK初始化账号Client
     *
     * @param accessKeyId
     * @param accessKeySecret
     * @return Client
     * @throws Exception
     */
    public static com.aliyun.dyplsapi20170525.Client createClient1(String accessKeyId, String accessKeySecret) throws Exception {
        Config config = new Config()
                // 您的AccessKey ID
                .setAccessKeyId(accessKeyId)
                // 您的AccessKey Secret
                .setAccessKeySecret(accessKeySecret);
        // 访问的域名
        config.endpoint = "dyplsapi.aliyuncs.com";
        return new com.aliyun.dyplsapi20170525.Client(config);
    }

    public Map getphoneHm(SyVirtualNumberVo syVirtualNumberVo) throws Exception {
        HashMap hashMap = new HashMap();
        try {
            //过期时间（分钟）
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String format = sdf.format(DateUtils.dateAddMinute(new Date(), syVirtualNumberVo.getExpiration()));
            com.aliyun.dyplsapi20170525.Client client = createClient1(syVirtualNumberVo.getAccessKeyId(), syVirtualNumberVo.getAccessKeySecret());
            BindAxnRequest bindAxnRequest = new BindAxnRequest().setPoolKey(syVirtualNumberVo.getPoolKey()) //号码池key
                    .setPhoneNoA(syVirtualNumberVo.getPhone())   //需要虚拟的手机号
                    .setExpiration(format);  //过期时间
            // 复制代码运行请自行打印 API 的返回值
            BindAxnResponse bindAxnResponse = client.bindAxn(bindAxnRequest);
            String code1 = bindAxnResponse.getBody().getCode();
            if (code1.equalsIgnoreCase("ok")) {
                //发送成功
                hashMap.put("data", bindAxnResponse.getBody().getSecretBindDTO().getSecretNo());
                hashMap.put("code", 200);
                hashMap.put("msg", "虚拟号创建成功");
            } else {
                //发送失败
                hashMap.put("code", 500);
                hashMap.put("msg", "虚拟号创建失败，请校验阿里云参数是否正确");
            }
        } catch (Exception e) {
            hashMap.put("code", 500);
            hashMap.put("msg", "虚拟号创建失败，请校验阿里云参数是否正确");
        }
        return hashMap;
    }



}